package com.kongjs.online.preview.controller;

import com.kongjs.online.preview.advice.OnlinePreviewException;
import com.kongjs.online.preview.config.OnlinePreviewConfiguration;
import com.kongjs.online.preview.utils.HttpUtils;
import com.kongjs.online.preview.utils.MsOfficeUtils;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.office.OfficeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileUrlResource;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("onlinePreview")
public class OnlinePreviewController {
    private static final Logger LOGGER = LoggerFactory.getLogger(OnlinePreviewController.class);
    @Autowired
    private OnlinePreviewConfiguration onlinePreviewConfiguration;
    @Autowired
    private DocumentConverter documentConverter;

    /**
     * 设置客户端无缓存Header.
     */
    private void setNoCacheHeader(HttpServletResponse response) {
        // Htt p 1.0 header
        response.addHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        // Http 1.1 header
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Cache-Control", "no-store");
    }

    @ResponseBody
    @ExceptionHandler
    public String errorView(OnlinePreviewException e) {
        return e.getMessage();
    }

    @GetMapping("/")
    public String file(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes, @RequestParam("url") String url) throws OnlinePreviewException {
        String reqUrl = request.getRequestURL().toString();
        String reqUri = request.getRequestURI();

        String onlinePreviewFileUri = onlinePreviewConfiguration.getOnlinePreviewFileUri();
        String onlinePreviewFileDir = onlinePreviewConfiguration.getOnlinePreviewFileDir();
        String onlinePreviewFileUrl = reqUrl.replace(reqUri, onlinePreviewFileUri);

        LOGGER.info("onlinePreviewFileUri ==> {}",onlinePreviewFileUri);
        LOGGER.info("onlinePreviewFileDir ==> {}",onlinePreviewFileDir);

        FileUrlResource fileUrlResource;
        try {
            LOGGER.info("预览文件 URL ==> {}",url);
            fileUrlResource = new FileUrlResource(url);
        } catch (MalformedURLException e) {
            throw new OnlinePreviewException("链接错误");
        }

        if (!fileUrlResource.isFile()) {
            throw new OnlinePreviewException("不是一个文件");
        }

        File fileUrlResourceFile;
        try {
            fileUrlResourceFile = fileUrlResource.getFile();
        } catch (IOException e) {
            throw new OnlinePreviewException("获取文件失败");
        }

        String filename = fileUrlResourceFile.getName();
        String filenameExtension = StringUtils.getFilenameExtension(filename);
        if (filenameExtension == null) {
            throw new OnlinePreviewException("文件名不正确");
        }

        String randomSuffix = UUID.randomUUID().toString().concat(".pdf");
        String pdfFileName = filename.replace(filenameExtension, randomSuffix);
        Path filePath = Paths.get(onlinePreviewFileDir, filename);
        Path pdfPath = Paths.get(onlinePreviewFileDir, pdfFileName);

        try {
            HttpUtils.download(url, filePath.toFile());
        } catch (Exception e) {
            throw new OnlinePreviewException("文件下载失败");
        }

        File officeDir = new File(onlinePreviewConfiguration.getMsOfficeHome());

        if (filenameExtension.equalsIgnoreCase("docx")) {
            MsOfficeUtils.wordToPdf(officeDir, 15, TimeUnit.SECONDS, fileUrlResourceFile, pdfPath.toFile());
        } else if (filenameExtension.equalsIgnoreCase("doc")) {
            MsOfficeUtils.wordToPdf(officeDir, 15, TimeUnit.SECONDS, fileUrlResourceFile, pdfPath.toFile());
        } else {
            try {
                documentConverter
                        .convert(filePath.toFile())
                        .to(pdfPath.toFile())
                        .execute();
            } catch (OfficeException e) {
                throw new OnlinePreviewException("预览转换失败");
            }
        }
        onlinePreviewFileUrl = onlinePreviewFileUrl.concat(pdfFileName);
        String view = "redirect:/onlinePreview/pdf";
        redirectAttributes.addAttribute("file", onlinePreviewFileUrl);
        this.setNoCacheHeader(response);
        return view;
    }

    @GetMapping("/pdf")
    public String pdf(HttpServletRequest request, HttpServletResponse response, @RequestParam(name = "file") String file) {
        LOGGER.info("file=" + file);
        this.setNoCacheHeader(response);
        return "/pdf/view.html?file=" + file;
    }

    @ResponseBody
    @GetMapping(path = "", produces = MediaType.TEXT_HTML_VALUE)
    public String index() {
        return "";
    }
}